import {
  Card,
  Breadcrumb,
  Form,
  Button,
  Radio,
  Input,
  Upload,
  Space,
  message,
} from 'antd'
import { PlusOutlined } from '@ant-design/icons'
import { Link } from 'react-router-dom'
import styles from './index.module.scss'
// 导入富文本编辑器
// 组件
import ReactQuill from 'react-quill'
// 样式
import 'react-quill/dist/quill.snow.css'
import Channel from '@/components/channel'
import { useEffect, useRef, useState } from 'react'
import { publishArticleAction } from '@/store/modules/article'
import { useDispatch } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import { useParams } from 'react-router-dom'
import { getArticleApi } from '@/api/article'

const Publish = () => {
  // 获取编辑文章ID
  const params = useParams()
  const articleId = params['*']
  // isEdit是否是编辑状态：true 编辑 | false 不是编辑（发布文章）
  const isEdit = !!articleId

  const dispatch = useDispatch()
  const hs = useNavigate()
  // 1. 上传图片，并存储到fileList中
  // 存储上传图片：[{url:''}...]
  const [fileList, setFileList] = useState([])
  const fileListBackup = useRef([])
  // 上传文件改变时的回调：1. 上传成功，返回图片地址 2. 删除已上传图片
  const onUploadChange = (data) => {
    console.log('upload:', data)
    const _fileList = data.fileList.map((file) => {
      //  1. 上传成功
      if (file.response) {
        //  上传成功后台返回的图片地址：file.response.data.url
        return {
          url: file.response.data.url,
        }
      }
      //  2. 已上传图片
      return file
    })
    // console.log('处理完的上传列表：', _fileList)
    // 备份上传的图片列表(始终是所有的)
    if (data.file.status !== 'removed') {
      fileListBackup.current = _fileList
    } else {
      fileListBackup.current = fileListBackup.current.filter(
        (item) => item.uid !== data.file.uid
      )
    }
    setFileList(_fileList)
  }

  // 2. 控制上传封面图数量
  const [maxCount, setMaxCount] = useState(1)
  const changeType = (e) => {
    const count = e.target.value
    // console.log('选择的上传图片数量：', e.target.value)
    setMaxCount(count)
    // 3. 控制切换图片的数量
    /**
     * 场景：选了上传>1 e.target.value <=3
     * 1. 选择单图 => 只显示第一张
     * 2. 选择三图 =》全部显示
     */
    console.log(222, fileListBackup.current)
    if (count === 1) {
      const first = fileListBackup.current[0]
      setFileList(!first ? [] : [first])
    } else if (count === 3) {
      setFileList(fileListBackup.current)
    }
  }

  // 4. 点击提交=》发布文章
  /**
   * 封装发布和存为草稿可复用方法=》函数重载
   * @param {*} formData 表单数据
   * @param {*} isDraft 是否发布为草稿  true 存为草稿 | false 发布文章
   * @returns
   */
  const publishArticle = async (formData, isDraft) => {
    // console.log('表单数据：', formData)
    // 1. 封面图片单独校验：选择封面的数量和fileList上传图片的数量相等
    const { type, ...sxd } = formData
    if (type !== fileList.length) {
      return message.warn('选择封面数量和上传图片数量不一致！')
    }
    // 2. 组装发布文章需要的接口参数
    // console.log('剩余参数：', sxd)
    const data = {
      ...sxd,
      cover: {
        type,
        // 封面图列表：['url1', 'url2',...]
        images: fileList.map((item) => item.url),
      },
    }
    // 如果是编辑，就将 id 存储到 data 中，传递给接口
    if (isEdit) {
      data.id = articleId
    }
    console.log('调用发布文章接口参数：', data)
    try {
      await dispatch(publishArticleAction(data, isDraft, isEdit))
      const text = isEdit ? '修改' : '发布'
      message.success(!isDraft ? `${text}文章成功！` : '存为草稿成功')
      hs('/article')
    } catch (error) {}
  }
  // 表达提交：发布文章
  const onFinish = (formData) => {
    publishArticle(formData, false)
  }

  // 5. 存为草稿
  // 获取表单实例
  const [form] = Form.useForm()
  const saveDraft = async () => {
    console.log('表单实例：', form)
    try {
      const formData = await form.validateFields()
      console.log('校验通过：', formData)
      // 存为草稿状态的文章
      publishArticle(formData, true)
    } catch (error) {
      console.log('校验失败：', error)
    }
  }

  // 6. 编辑文章
  // 回填数据
  useEffect(() => {
    // 不是编辑状态直接return，不进行数据回填
    if (!isEdit) return
    ;(async () => {
      try {
        // 1. 获取回填数据
        const { data } = await getArticleApi(articleId)
        console.log('回填数据：', data)
        // 2. 进行回填
        const {
          title,
          content,
          channel_id,
          cover: { type, images },
        } = data
        // 通过form实例提供的setFieldsValue(表单数据formData),回填表单
        // 3. 准备表单回填需要的数据fromData
        const formData = { title, content, channel_id, type }
        form.setFieldsValue(formData)
        // 4. 回填之前上传过的图片
        // 格式：存储上传图片：[{url:''}...]
        const imgList = images.map((item) => ({ url: item }))
        // 回显上传过的图片
        setFileList(imgList)
        // 备份
        fileListBackup.current = imgList
        // 设置最大上传数量
        setMaxCount(type)
      } catch (error) {
        console.log(error)
      }
    })()
  }, [articleId, isEdit, form])

  useEffect(() => {
    console.log('参数变了：', params, form.getFieldValue('title'))
    if (!params['*'] && form.getFieldValue('title')) {
      form.resetFields()
      setFileList([])
    }
  }, [params, form])

  return (
    <div className={styles.root}>
      <Card
        title={
          <Breadcrumb separator=">">
            <Breadcrumb.Item>
              <Link to="/">首页</Link>
            </Breadcrumb.Item>
            <Breadcrumb.Item>
              {!isEdit ? '发布文章' : '编辑文章'}
            </Breadcrumb.Item>
          </Breadcrumb>
        }
      >
        <Form
          form={form}
          onFinish={onFinish}
          // labelCol={{ span: 2 }}
          // wrapperCol={{ span: 20 }}
          initialValues={{ type: 1, content: '' }}
        >
          {/* 文章标题 */}
          <Form.Item
            label="标题"
            name="title"
            rules={[{ required: true, message: '请输入文章标题' }]}
          >
            <Input placeholder="请输入文章标题" style={{ width: 400 }} />
          </Form.Item>
          {/* 文章频道 */}
          <Form.Item
            label="频道"
            name="channel_id"
            rules={[{ required: true, message: '请选择文章频道' }]}
          >
            {/* <Select placeholder="请选择文章频道" style={{ width: 400 }}>
              <Option value={0}>推荐</Option>
            </Select> */}
            <Channel width={400} />
          </Form.Item>
          {/* 文章封面图 */}
          <Form.Item label="封面">
            {/* 1. 封面图数量单选 */}
            <Form.Item name="type">
              <Radio.Group onChange={changeType}>
                <Radio value={1}>单图</Radio>
                <Radio value={3}>三图</Radio>
                <Radio value={0}>无图</Radio>
                {/* <Radio value={-1}>自动</Radio> */}
              </Radio.Group>
            </Form.Item>
            {/* 上传图片组件 */}
            {/* // Upload 组件说明： */}
            {maxCount > 0 && (
              <Upload
                className="avatar-uploader"
                // 控制上传图片的数量
                maxCount={maxCount}
                // 多选=》是否支持多选文件上传
                multiple={maxCount > 1}
                // 发到后台的文件参数名
                // === 2. 必须指定，根据接口文档的说明，需要设置为 image ===
                name="image"
                // 接口地址
                // 注意：Upload 再上传图片时，默认不会执行 axios 的请求，所以，此处需要手动设置完整接口地址
                // 1. 必传后台上传的接口地址
                action="http://geek.itheima.net/v1_0/upload"
                // 上传组件展示方式
                listType="picture-card"
                // 展示已上传图片列表
                showUploadList
                // 已经上传的文件列表，设置该属性后组件变为 受控
                fileList={fileList}
                // 上传文件改变时的回调：1. 上传成功，返回图片地址 2. 删除已上传图片
                onChange={onUploadChange}
              >
                <div style={{ marginTop: 8 }}>
                  <PlusOutlined />
                </div>
              </Upload>
            )}
          </Form.Item>
          {/* 文章内容 */}
          <Form.Item
            label="内容"
            name="content"
            rules={[{ required: true, message: '请输入文章内容' }]}
          >
            {/* 富文本编辑器:
            说明：结合antd的form组件使用，不用自己手动受控处理；因为：Form.Item会自动
            向ReactQuill添加受控处理：value状态+onChange事件
            注意：编辑器组件必须初始化默认值，不然不会报错
            */}
            <ReactQuill className="quill-box" />
          </Form.Item>
          {/* 表单提交 */}
          <Form.Item wrapperCol={{ offset: 4 }}>
            <Space>
              {/* 正式发布 */}
              <Button size="large" type="primary" htmlType="submit">
                {!isEdit ? '发布文章' : '编辑文章'}
              </Button>
              {/* 暂存 */}
              <Button onClick={saveDraft} size="large">
                存入草稿
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </Card>
    </div>
  )
}

export default Publish
